import {json_encode, json_decode, json_decode_object, decode_config} from "@/js/s94_tool.js";
import s94Mjs from "s94-js";
import {_get} from "@/vue_plugin/router_auto.js";
import S94Mjs from "s94-js";
import {use_config_map} from "@/store/config_map.js";
import {use_this_user} from "@/store/this_user.js";
import {use_this_admin} from "@/store/this_admin.js";

function to_string(v){
    switch (typeof v) {
        case 'boolean': {v = v ? 1 : 0;} break;
        case 'object': {v = JSON.stringify(v);} break;
    }
    return s94Mjs.to_string(v);
}

class S94Compute{
    constructor(info){
        this.info = info;
        this.input = _get();
    }

    display(code){
        if (/^\w+\([\s\S]*\)$/.test(code)){
            return this.compute(code);
        }else {
            return this.outString(code);
        }
    }

    compute(code) {
        code = s94Mjs.to_string(code);
        if (!code) return "";
        if (!/^\w+\([\s\S]*\)$/.test(code)) throw `计算代码只能为已存在函数，计算代码：${code}`;
        let run_code = 'return ' + code.replaceAll('$this->', 'this.')
            .replace(/\w+\(/g, 'this.$&')
            .replace(/\$(input|info)/g, 'this.$1');
        let run_func = new Function(run_code);
        try {
            return run_func.call(this);
        } catch (e) {
            console.error(e);
            return code;
        }
    }
    outString(output) {
        output = s94Mjs.to_string(output);
        let count = 1;
        while (count > 0){
            count = 0;
            output = output.replace(/`(\w+\([\s\S]*\))`/, (m0, m1)=>{
                count++;
                let res = to_string(this.compute(m1));
                return res;
            });
        }
        return output;
    }

    // ---------------------------------- 以下为处理方法 -----------------------------

    get(data, key, def){
        return s94Mjs.map(data, key, def);
    }
    get_true(data, ...keys){
        let res = '';
        keys.some(key=>{
            res = s94Mjs.map(data, key);
            return !!res;
        })
        return res;
    }
    list_get(list, key, index_key){
        let res = [];
        Object.values(list).forEach(data=>{
            let v = s94Mjs.map(data, key);
            let k = index_key ? s94Mjs.map(data, index_key) : '';
            if (k){
                res[k] = v;
            }else {
                res.push(v);
            }
        })
        return res;
    }
    list_get_true(list, ...keys){
        let res = [];
        Object.values(list).forEach(data=>{
            let v = this.get_true(data, ...keys);
            res.push(v);
        })
        return res;
    }
    join(list, separator=','){
        return Object.values(list).join(separator);
    }
    list_sort(list, key){
        return []
    }
    list_gte(list,key,value){
        return []
    }
    list_lte(list,key,value){
        return []
    }
    concat(...args) {
        let resType = "";

        // 确定结果类型
        for (const v of args) {
            if (v === null || v === undefined) continue;
            if (resType === "string") break;

            let type;
            if (Array.isArray(v) || (typeof v === 'object' && v !== null)) {
                type = "array";
            } else if (typeof v === 'number' && !isNaN(v)) {
                type = "number";
            } else {
                type = "string";
            }

            if (!resType) {
                resType = type;
            } else {
                if (resType !== type) resType = "string";
            }
        }

        // 过滤掉 null 和 undefined
        const filteredArgs = args.filter(arg => arg !== null && arg !== undefined);

        // 根据类型处理
        switch (resType) {
            case "array":
                return filteredArgs.reduce((acc, val) => acc.concat(val), []);
            case "number":
                return filteredArgs.reduce((sum, num) => sum + Number(num), 0);
            default:
                return filteredArgs.map(v => to_string(v)).join('');
        }
    }
    ratio(value, rate){

    }
    list_ratio(list, rate){

    }
    round(num, precision){

    }
    json_encode(value){
        return json_encode(value);
    }
    json_decode(json){
        return json_decode(json);
    }
    json_decode_object(json){
        return json_decode_object(json);
    }
    length(val){

    }
    db_find(table, where){

    }
    db_list(table, where){

    }
    db_count(table, where, no_base_where){

    }
    db_sum(table, where, field, no_base_where){

    }
    unique(list){

    }
    unique_eq(list){

    }
    _if(ex, fail, ok){
        if (ex){
            return typeof ok === 'undefined' ? ex : ok;
        }else {
            return fail;
        }
    }
    indexof(val, need){
        let i = val.indexOf(need);
        return i===-1 ? null : i;
    }
    config(name, def){
        return S94Mjs.map(use_config_map().config, name, def);
    }
    date(fmt, time){
        return S94Mjs.date(fmt, time);
    }

    this_user(key='id'){
        return S94Mjs.map(use_this_user(), key);
    }
    this_admin(key='id'){
        return S94Mjs.map(use_this_admin(), key);
    }
    this_tenant(key='id'){
        return S94Mjs.map(use_config_map().this_tenant, key);
    }
    model_map(switch_key){
        return use_config_map().model_map;
    }
    pay_type_map(is_all){

    }
    status_map(model_name){

    }
    pay_status_map(model_name){

    }
    time_range_map(time_list, range, start, day_num){
        start = start || 0;
        day_num = day_num || 5;
    }
    option_str(list, content_key, value_key, children_key){
        content_key = content_key || 'content';
        value_key = value_key || 'value';
        children_key = children_key || 'children';
        return decode_config(list, {
            content_key: content_key,
            value_key: value_key,
            children_key: children_key,
        })
    }
    user_money(user_id){
        return 0;
    }
    compute_price(){

    }
    pay_money(){

    }
    batch_action(){

    }
    owned(){

    }
    owned_time(){

    }
    owned_surplus(){

    }
    replace(){

    }
}


export default S94Compute;


